#include "Node.h"

// KONSTRUKTOR - DESTRUKTOR
nodeList 	CreateEmptyNodeList() {
	nodeList NL;
	FIRST(NL) = NULL;
	return NL;
}

nodeAddress AllocateNode(string name, float retrieveTime, float updateTime, float insertTime, float deleteTime, bool hasClient, bool hasServer) {
	return AllocateNodeAdv(name, retrieveTime, updateTime, insertTime, deleteTime, hasClient, hasServer, NULL);
}

nodeAddress AllocateNodeAdv(string name, float retrieveTime, float updateTime, float insertTime, float deleteTime, bool hasClient, bool hasServer, nodeAddress next) {
	nodeAddress n = (nodeAddress) malloc(sizeof(node));
	if (n != NULL)
		{
			NODENAME(n) = name; 		
			RETRIEVETIME(n) = retrieveTime;
			UPDATETIME(n) = updateTime;
			INSERTTIME(n) = insertTime;
			DELETETIME(n) = deleteTime;
			HAS_CLIENT(n) = hasClient;
			HAS_SERVER(n) = hasServer;
			HAS_TMHS(n) = false;
			HAS_TMK(n) = false;
			HAS_TPMK(n) = false;
			NEXT(n) = next;
		}
	return n;
}

void		DeallocateNode(node *n) {
	free(n);
}

// PREDIKAT
bool 		IsNodeEqual(nodeAddress A, nodeAddress B) {
	return IsStringEqual(NODENAME(A),NODENAME(B));
}

// OPERASI
void		ChangeNodeTableAvailability(nodeAddress node, bool hasTMhs_baru, bool hasTMK_baru, bool hasTPMK_baru) {
	HAS_TMHS(node) = hasTMhs_baru;
	HAS_TMK(node) = hasTMK_baru;
	HAS_TPMK(node) = hasTPMK_baru;
}

nodeAddress SearchNodeByName(nodeList *NL, string name) {
	if(ISLINKEDLISTEMPTY(*NL)) return NULL;
	else if(IsStringEqual(name, NODENAME(FIRST(*NL)))) {
		return FIRST(*NL);
	}
	else {
		nodeAddress n = NULL;
		TRAVERSETOEND(n,FIRST(*NL))
			if(IsStringEqual(name,NODENAME(NEXT(n)))) break;
		return NEXT(n);
	}
}

void AddNode(nodeList *NL, nodeAddress node) {
	if(ISLINKEDLISTEMPTY(*NL) || IsStringLt(NODENAME(node), NODENAME(FIRST(*NL)))) {
		NEXT(node) = FIRST(*NL);
		FIRST(*NL) = node;
	}
	else {
		nodeAddress n = NULL;
		TRAVERSETOEND(n,FIRST(*NL))
			if(IsStringLt(NODENAME(node),NODENAME(NEXT(n)))) break;
		
		NEXT(node) = NEXT(n);
		NEXT(n) = node;
	}
}

void		DestroyNode(nodeList *NL, nodeAddress node) {
	if(FIRST(*NL)==node) {
		FIRST(*NL)=NEXT(node);
	}
	else {
		nodeAddress n;
		TRAVERSETOEND(n,FIRST(*NL))
			if(NEXT(n) == node) break;
			
		NEXT(n) = NEXT(node);
	}
	
	DeallocateNode(node);
}

void		DestroyNodeList(nodeList *NL) {
	nodeAddress M;
	TRAVERSETOEND2(M,FIRST(*NL)) {
		DestroyNode(NL,M);
	}
}


void PrintNode(nodeAddress N){
    char UpParam[100];
    int Down;
    int Count;
    char SITES[15]=" sites ";
    char SERVERS[15]=" servers ";
    char CLIENTS[15]=" clients ";
    char TABLES[15]=" tables ";
    char CONNECTIONS[25]=" connections ";
    char ASC[10] = " asc ";
    char DESC[10] = " desc ";
    char STR[250];
    
    if (N!=NULL) {
    sprintf(STR,"%s",NODENAME(N).s);
    AddSpace(STR,"site");
    printf("%s",STR);
            
                HAS_SERVER(N)?sprintf(STR,"Ya"):sprintf(STR,"Tidak");
                AddSpace(STR,"server");
                printf("%s",STR);                               
             
           
                HAS_CLIENT(N)?sprintf(STR,"Ya"):sprintf(STR,"Tidak");
                AddSpace(STR,"client");
                printf("%s",STR);  
            
            if (HAS_SERVER(N)){
                sprintf(STR,"%.4f",RETRIEVETIME(N));
                AddSpace(STR,"retrieve");
                printf("%s",STR);
                sprintf(STR,"%.4f",UPDATETIME(N));
                AddSpace(STR,"update");
                printf("%s",STR);
                sprintf(STR,"%.4f",INSERTTIME(N));
                AddSpace(STR,"insert");
                printf("%s",STR);
                sprintf(STR,"%.4f",DELETETIME(N));
                AddSpace(STR,"delete");
                printf("%s",STR); 
                }
            }          
     printf("\n");                           
}

void	PrintNodeHeader() {
        char STR[250];
        // SetColor(FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);                                      
        sprintf(STR,"Site");
        AddSpace(STR,"site");
        printf("%s",STR);
        sprintf(STR,"Server");
        AddSpace(STR,"server");
        printf("%s",STR);
        sprintf(STR,"Client");
        AddSpace(STR,"client");
        printf("%s",STR);
        sprintf(STR,"Retrieve");
        AddSpace(STR,"retrieve");
        printf("%s",STR); 
        sprintf(STR,"Update");
        AddSpace(STR,"update");
        printf("%s",STR);
        sprintf(STR,"Insert");
        AddSpace(STR,"insert");
        printf("%s",STR);
        sprintf(STR,"Delete");
        AddSpace(STR,"delete");
        printf("%s\n",STR);
        // SetColor(FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY);
        
}
